-
Notifications
You must be signed in to change notification settings - Fork 106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat!: throw error with out of bounds integer values instead of truncating, add custom 'integerValue' type cast option #488
Conversation
Codecov Report
@@ Coverage Diff @@
## master #488 +/- ##
==========================================
+ Coverage 98.22% 98.27% +0.04%
==========================================
Files 6 6
Lines 734 753 +19
Branches 172 178 +6
==========================================
+ Hits 721 740 +19
Misses 2 2
Partials 11 11
Continue to review full report at Codecov.
|
@crwilcox were we comfortable with making this a major release of datastore? I know we're trying to keep major bumps infrequent, but this seems like a reasonably useful refactor to consider one. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So just a general note, I didn't realize that the type cast function would only apply to integers. Not sure if I missed a separate conversation leading to this PR, but I think this would be useful for all data types, not just integers.
My logic here is, that library doesn't have an issue with correctly obtaining all other value types and if any conversions/manipulations are required, the user can do them after getting the values from this library. With regards to numeric types there is an issue of obtaining accurate large integer values. Another point is, I wouldn't want to incorporate third party code more than I have to. Not to subjugate the library to performance impact, bugs, etc... from third party. |
@AVaksman makes sense, I might be bikeshedding but if this only applies to integers we might want to revisit the name? Though if no one else feels the same way I don't feel super strongly about it 😄 |
Refactored to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on the PR description, I can't really figure out what the breaking change is. Can you add a really clear message in there for the release notes, including before code and after code?
The breaking part is that now in case of Users who needed to accurately obtain out of bounds integer values, couldn't. So they probably didn't use this functionality, hence practically speaking this is not breaking change. |
@@ -372,7 +435,7 @@ export namespace entity { | |||
} | |||
|
|||
case 'integerValue': { | |||
return Number(value); | |||
return decodeIntegerValue(valueProto, integerTypeCastOptions); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is definitely a more robust option, but was just returning the DS.Int type considered?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I mixed up Datastore's "Int" with Spanner's: https://github.com/googleapis/nodejs-spanner/blob/f8ad0ece28e99dd9c6d7e985de56bd1b376f4712/src/codec.ts#L139 -- for simplicity's sake, would it be worth considering using that format instead? When a value is out of bounds, it will throw. The value is accessible via the "value" property in string form.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- I do like the ability to still access the value in string form without extra network call in case of value is out of balance.
- it will definitely be a breaking change.
- IMO it will add complexity to the user's code.
will need totry=>catch
forvalueOf
and iferror
still pass thevalue
to customtypeCastFunction
. - Is it overkill to combine these two approaches?
- return Spanner's style object for
integerValue
. - for
valueOf
on default throw in case of out of bounds. - able to pass integerTypeCastFunction and
valueOf
will return the custom function result.
- return Spanner's style object for
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- I do like the ability to still access the value in string form without extra network call in case of value is out of balance.
Sorry if I misunderstand. Neither of the solutions make an extra network call, do they?
- it will definitely be a breaking change.
I think the throwing behavior is identical to what is in this PR. It will first try to just use it as a number, but if it's out of bounds when called upon, it throws. Or, is it because the new "Int" wrapper isn't technically a Number
? Lots of gray area in determining a breaking change 😕
- Is it overkill to combine these two approaches?
I quite like that approach! Maybe @callmehiphop has a thought on this, too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for clearing that up for me! For the Number vs customer "Int" type issue, they can at least be used interchangeably, the only difference would be typeof
checks for Number wouldn't pass... unless Int extended Number? Curious to hear other thoughts on the best way to go forward.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did we ever make progress on this, maybe in another chat?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quick summary
Would like to hear the thoughts on the approach
- Throw on default, let user pass integerTypeCastFunction (currently implemented in this PR)
- Return an object
Integer
similar to Spanner, where#valueOf
would try to convert toNumber
and throw if out of bounds#value
returnsstring
representation of the value
- Combine tow approaches above
- do return an
Integer
object - let user provide integerTypeCast function to be used by
#valueOf
- still return string via
#value
- do return an
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My vote would go for #3. Ping to @callmehiphop and @bcoe for more votes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My vote is starting simple with option 1, as a breaking change, and we can move towards an object representation in the future, if there's good reason.
@AVaksman ah in that case - can you drop the |
Roger that |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's call this feature out in the README.md, specifically explaining how to setup a typecast function to avoid an out of bounds.
@jkwlui Does everything look good here for you after the latest fixes? |
Quick summary
from @stephenplusplus
|
@AVaksman maybe it'll just be us deciding 😆 What is your preference? |
@stephenplusplus I do like option 3 as well, @bcoe 's vote goes to # 1 |
@AVaksman @stephenplusplus @bcoe what's the next steps here? |
The next step would be to decide between approach in this PR vs #516 |
I don't see us going back to this after where we landed in #516, so I'll just close for now to avoid any confusion. |
Fixes #147
As per discussion, implementation follows design in the document
Number
typeCastFunction
to be used to convert integer valuestypeCastFunction